package com.zzyl.nursing.service.impl;


import java.time.LocalDateTime;
import java.util.List;

import cn.hutool.json.JSONUtil;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.IDCardUtils;
import com.zzyl.common.utils.PDFUtil;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.ai.BaiduQianfanAIModelUtil;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.vo.health.HealthReportVo;
import com.zzyl.oss.AliyunOSSOperator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;

import static com.zzyl.common.constant.CacheConstants.HEALTH_REPORT_KEY;
import static com.zzyl.common.constant.Constants.HEALTH_REPORT_PROMPT_TEMPLATE;

/**
 * 健康评估Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-22
 */
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private BaiduQianfanAIModelUtil aiModelUtil;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessmentDto 健康评估 0222
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto) {
        //组装prompt提示词
        String prompt = this.getPrompt(healthAssessmentDto.getIdCard());

        //调用AI模型,返回结果(结果为Json格式)
        String aiAnswer = aiModelUtil.invoke(prompt);

        //解析ai模型返回结果
        HealthReportVo aiReport = JSONUtil.toBean(aiAnswer, HealthReportVo.class);
        Long id = saveHealthAccessment(aiReport, healthAssessmentDto);


        //保存到数据库并返回主键

        return null;
    }

    /**
     * @param aiReport
     * @param formData
     * @return
     */
    private Long saveHealthAccessment(HealthReportVo aiReport, HealthAssessmentDto formData) {
        HealthAssessment healthAssessment = new HealthAssessment();
        //1.添加老人基本信息
        String idCard = formData.getIdCard();
        healthAssessment.setElderName(formData.getElderName());
        healthAssessment.setIdCard(idCard);
        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(idCard));
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(idCard));
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(idCard));
        healthAssessment.setPhysicalExamInstitution(formData.getPhysicalExamInstitution());
        healthAssessment.setPhysicalReportUrl(formData.getPhysicalReportUrl());
        healthAssessment.setAssessmentTime(LocalDateTime.now());
        healthAssessment.setTotalCheckDate(aiReport.getTotalCheckDate());

        //2、添加体检总结信息
        double score = aiReport.getHealthAssessment().getHealthIndex();
        healthAssessment.setHealthScore(String.valueOf(score));  // 健康评分（AI）
        healthAssessment.setRiskLevel(aiReport.getHealthAssessment().getRiskLevel()); // 风险等级（AI）
        healthAssessment.setSuggestionForAdmission(score > 60 ? 0 : 1);  // 是否建议入住（AI）
        healthAssessment.setNursingLevelName(getNursingLevelName(score));  // 推荐护理等级（根据健康评分计算）
        healthAssessment.setAdmissionStatus(1);  // 入住情况（未入住）
        healthAssessment.setAssessmentTime(LocalDateTime.now()); // 评估时间（当前时间）
        healthAssessment.setReportSummary(aiReport.getSummarize()); // 报告总结（AI）


        //3.添加疾病风险&健康指数
        healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(aiReport.getAbnormalData()));
        healthAssessment.setSystemScore(JSONUtil.toJsonStr(aiReport.getSystemScore()));

        //4.添加异常分析信息
        healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(aiReport.getAbnormalData()));

        healthAssessmentMapper.insert(healthAssessment);

        return healthAssessment.getId();
    }

    /**
     * 得到推荐护理等级
     *
     * @param score
     * @return
     */
    private String getNursingLevelName(double score) {
        if (score >= 90) {
            return "三级护理";
        } else if (score >= 80) {
            return "二级护理";
        } else if (score >= 70) {
            return "一级护理";
        } else if (score >= 60) {
            return "特级护理";
        } else {
            return "不建议入院";
        }
    }

    /**
     * 提示词组装
     *
     * @param idCard
     * @return
     */
    private String getPrompt(String idCard) {
        // 1、先从Redis查询体检报告内容 & 清除redis缓存数据
        String report = (String) redisTemplate.opsForHash().get(HEALTH_REPORT_KEY, idCard);
        redisTemplate.opsForHash().delete(HEALTH_REPORT_KEY, idCard);

        // 2、组装提示词
        String prompt = StringUtils.format(HEALTH_REPORT_PROMPT_TEMPLATE, report);

        // 3、返回
        return prompt;
    }


    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 体检报告上传
     *
     * @param file
     * @param idCardNo 0222
     * @return
     */
    @Override
    public String upload(String idCardNo, MultipartFile file) throws Exception {
        // 1、将文件存储到OSS
        String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());

        // 2、读取PDF文件内容
        String pdfCotent = PDFUtil.pdfToString(file.getInputStream());
        if (StringUtils.isEmpty(pdfCotent)) {
            throw new BaseException("PDF文件内容读取失败");
        }

        // 3、将PDF文件内容存储到Redis,并返回url
        redisTemplate.opsForHash().put(HEALTH_REPORT_KEY, idCardNo, pdfCotent);


        return url;
    }
}
